<template>
  <div class="log-viewer">
    <el-drawer
      v-model="visible"
      title="日志查看器"
      direction="btt"
      size="60%"
      :before-close="handleClose"
    >
      <div class="log-controls">
        <el-row :gutter="16" align="middle">
          <el-col :span="6">
            <el-select v-model="selectedLevel" placeholder="选择日志级别" @change="filterLogs">
              <el-option label="全部" value="all" />
              <el-option label="DEBUG" :value="LOG_LEVELS.DEBUG" />
              <el-option label="INFO" :value="LOG_LEVELS.INFO" />
              <el-option label="WARN" :value="LOG_LEVELS.WARN" />
              <el-option label="ERROR" :value="LOG_LEVELS.ERROR" />
            </el-select>
          </el-col>
          <el-col :span="6">
            <el-select v-model="selectedLogger" placeholder="选择日志器" @change="filterLogs">
              <el-option label="全部" value="all" />
              <el-option v-for="logger in loggerNames" :key="logger" :label="logger" :value="logger" />
            </el-select>
          </el-col>
          <el-col :span="4">
            <el-input-number v-model="maxLogs" :min="10" :max="1000" :step="10" @change="filterLogs" />
          </el-col>
          <el-col :span="8">
            <el-button @click="refreshLogs">刷新</el-button>
            <el-button @click="clearLogs">清空</el-button>
            <el-button @click="exportLogs">导出</el-button>
            <el-button @click="toggleAutoScroll">
              {{ autoScroll ? '停止滚动' : '自动滚动' }}
            </el-button>
          </el-col>
        </el-row>
      </div>
      
      <div class="log-stats">
        <el-row :gutter="16">
          <el-col :span="6">
            <el-statistic title="总日志数" :value="totalLogs" />
          </el-col>
          <el-col :span="6">
            <el-statistic title="错误数" :value="errorCount" />
          </el-col>
          <el-col :span="6">
            <el-statistic title="警告数" :value="warnCount" />
          </el-col>
          <el-col :span="6">
            <el-statistic title="信息数" :value="infoCount" />
          </el-col>
        </el-row>
      </div>
      
      <div ref="logContainer" class="log-container">
        <div
          v-for="(log, index) in filteredLogs"
          :key="index"
          :class="['log-entry', `log-${log.levelName.toLowerCase()}`]"
        >
          <div class="log-header">
            <span class="log-timestamp">{{ formatTime(log.timestamp) }}</span>
            <span :class="['log-level', `level-${log.levelName.toLowerCase()}`]">
              {{ log.levelName }}
            </span>
            <span class="log-logger">{{ log.logger }}</span>
          </div>
          <div class="log-message">{{ log.message }}</div>
          <div v-if="log.data" class="log-data">
            <pre>{{ JSON.stringify(log.data, null, 2) }}</pre>
          </div>
          <div v-if="log.error" class="log-error">
            <details>
              <summary>错误详情</summary>
              <pre>{{ log.error.stack || log.error.message }}</pre>
            </details>
          </div>
        </div>
      </div>
    </el-drawer>
    
    <!-- 浮动按钮 -->
    <el-button
      v-if="!visible"
      type="primary"
      class="log-toggle-btn"
      circle
      @click="toggleViewer"
    >
      <el-icon><Document /></el-icon>
    </el-button>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { Document } from '@element-plus/icons-vue'
import { logger, LOG_LEVELS } from '@/utils/logger'

const visible = ref(false)
const logs = ref([])
const selectedLevel = ref('all')
const selectedLogger = ref('all')
const maxLogs = ref(100)
const autoScroll = ref(true)
const logContainer = ref(null)

// 统计信息
const totalLogs = computed(() => logs.value.length)
const errorCount = computed(() => logs.value.filter(log => log.level === LOG_LEVELS.ERROR).length)
const warnCount = computed(() => logs.value.filter(log => log.level === LOG_LEVELS.WARN).length)
const infoCount = computed(() => logs.value.filter(log => log.level === LOG_LEVELS.INFO).length)

// 日志器名称列表
const loggerNames = computed(() => {
  const names = new Set(logs.value.map(log => log.logger))
  return Array.from(names).sort()
})

// 过滤后的日志
const filteredLogs = computed(() => {
  let filtered = logs.value
  
  // 按级别过滤
  if (selectedLevel.value !== 'all') {
    filtered = filtered.filter(log => log.level >= selectedLevel.value)
  }
  
  // 按日志器过滤
  if (selectedLogger.value !== 'all') {
    filtered = filtered.filter(log => log.logger === selectedLogger.value)
  }
  
  // 限制数量
  return filtered.slice(-maxLogs.value)
})

// 格式化时间
const formatTime = (timestamp) => {
  return new Date(timestamp).toLocaleTimeString()
}

// 刷新日志
const refreshLogs = () => {
  logs.value = logger.getLogs()
  scrollToBottom()
}

// 过滤日志
const filterLogs = () => {
  nextTick(() => {
    scrollToBottom()
  })
}

// 清空日志
const clearLogs = () => {
  logger.clearLogs()
  logs.value = []
}

// 导出日志
const exportLogs = () => {
  const logText = logger.exportLogs()
  const blob = new Blob([logText], { type: 'text/plain' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `flink-web-logs-${new Date().toISOString().slice(0, 10)}.txt`
  a.click()
  URL.revokeObjectURL(url)
}

// 切换自动滚动
const toggleAutoScroll = () => {
  autoScroll.value = !autoScroll.value
  if (autoScroll.value) {
    scrollToBottom()
  }
}

// 滚动到底部
const scrollToBottom = () => {
  if (autoScroll.value && logContainer.value) {
    nextTick(() => {
      logContainer.value.scrollTop = logContainer.value.scrollHeight
    })
  }
}

// 切换查看器
const toggleViewer = () => {
  visible.value = !visible.value
  if (visible.value) {
    refreshLogs()
  }
}

// 关闭处理
const handleClose = () => {
  visible.value = false
}

// 定时刷新
let refreshTimer = null

onMounted(() => {
  // 只在开发环境显示
  if (import.meta.env.DEV) {
    refreshLogs()
    // 每秒刷新一次
    refreshTimer = setInterval(() => {
      if (visible.value) {
        refreshLogs()
      }
    }, 1000)
  }
})

onUnmounted(() => {
  if (refreshTimer) {
    clearInterval(refreshTimer)
  }
})
</script>

<style scoped>
.log-viewer {
  position: relative;
}

.log-toggle-btn {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 1000;
}

.log-controls {
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
  background: #f5f7fa;
}

.log-stats {
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
  background: #fafafa;
}

.log-container {
  height: 400px;
  overflow-y: auto;
  padding: 8px;
  font-family: 'Courier New', monospace;
  font-size: 12px;
}

.log-entry {
  margin-bottom: 8px;
  padding: 8px;
  border-radius: 4px;
  border-left: 3px solid #ddd;
}

.log-entry.log-debug {
  background: #f8f9fa;
  border-left-color: #6c757d;
}

.log-entry.log-info {
  background: #e7f3ff;
  border-left-color: #0dcaf0;
}

.log-entry.log-warn {
  background: #fff3cd;
  border-left-color: #ffc107;
}

.log-entry.log-error {
  background: #f8d7da;
  border-left-color: #dc3545;
}

.log-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
  font-weight: bold;
}

.log-timestamp {
  color: #6c757d;
  font-size: 11px;
}

.log-level {
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: bold;
}

.level-debug {
  background: #6c757d;
  color: white;
}

.level-info {
  background: #0dcaf0;
  color: white;
}

.level-warn {
  background: #ffc107;
  color: black;
}

.level-error {
  background: #dc3545;
  color: white;
}

.log-logger {
  color: #495057;
  font-size: 11px;
}

.log-message {
  margin-bottom: 4px;
  white-space: pre-wrap;
}

.log-data {
  background: #f8f9fa;
  border: 1px solid #dee2e6;
  border-radius: 3px;
  padding: 8px;
  margin-top: 4px;
}

.log-data pre {
  margin: 0;
  font-size: 11px;
  color: #495057;
}

.log-error {
  margin-top: 4px;
}

.log-error details {
  cursor: pointer;
}

.log-error pre {
  margin: 4px 0 0 0;
  font-size: 11px;
  color: #dc3545;
}
</style>

